package com.miaoyi.redisdemo.service.impl;


import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miaoyi.redisdemo.entity.WxLotteryPrize;
import com.miaoyi.redisdemo.entity.WxLotteryPrizeRecord;
import com.miaoyi.redisdemo.mapper.WxLotteryPrizeMapper;
import com.miaoyi.redisdemo.service.WxLotteryPrizeRecordService;
import com.miaoyi.redisdemo.service.WxLotteryPrizeService;
import com.miaoyi.redisdemo.utils.MyBusinessException;
import com.miaoyi.redisdemo.utils.RedisConstants;
import constans.R;
import constans.ReturnCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 奖品表 服务实现类
 * </p>
 *
 * @author hhh
 * @since 2023-11-17
 */
@Service
@Slf4j
public class WxLotteryPrizeServiceImpl extends ServiceImpl<WxLotteryPrizeMapper, WxLotteryPrize> implements WxLotteryPrizeService {


    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private WxLotteryPrizeRecordService lotteryPrizeRecordService;
    @Autowired
    @Lazy
    private WxLotteryPrizeService lotteryPrizeService;

    private Map<String,Object> cache = new HashMap<>();


    @Override
    @Transactional//需要保证原子性  如果是分布式使用tcc
    public R solveupdate(WxLotteryPrize prize) {
         Map<String,Object> cache = new HashMap<>();
        Long id = prize.getId();
        if (id == null) {
            return R.failed("id不能为空");
        }
        updateById(prize);

        stringRedisTemplate.delete(RedisConstants.CACHE_PRIZE_KEY + id);

        return R.ok();
    }

    @Override
    public R shiwu() {
        WxLotteryPrize prize = getById(1);
        if (prize == null) {
            return R.failed("商品不存在");
        }
        List<String> list = Stream.of("135364", "135365", "135366", "135367").collect(Collectors.toList());
        Collections.shuffle(list);
        String phone = list.get(0);//模拟多个人
        //synchronized(userId.toString().intern()){ }
        synchronized (phone.intern()) {
            lotteryPrizeService.saveprize(prize, phone);
        }
        return R.ok();
    }
    @Transactional
    public void saveprize(WxLotteryPrize prize, String phone) {
        int count = lotteryPrizeRecordService.count(Wrappers.lambdaQuery(WxLotteryPrizeRecord.class)
                .eq(WxLotteryPrizeRecord::getPhone, phone)
                .eq(WxLotteryPrizeRecord::getPrizeName, prize.getPrizeName()));
        if (count > 0) {
            throw new MyBusinessException(ReturnCode.ALREADYDONE, "已经购买");
        }
        boolean success = update(Wrappers.lambdaUpdate(WxLotteryPrize.class)
                .eq(WxLotteryPrize::getId, 1).gt(WxLotteryPrize::getPrizeNum, 0)
                .setSql("prize_num= prize_num -1"));
        if (!success) {
            // 扣减失败
            log.error("库存不足！");
            throw new MyBusinessException(ReturnCode.ALREADYDONE, "库存不足");
        }
        WxLotteryPrizeRecord record = new WxLotteryPrizeRecord();
        record.setPhone(phone);
        record.setPrizeName(prize.getPrizeName());
        record.setCreateTime(new Date());
        lotteryPrizeRecordService.save(record);

        //throw new MyBusinessException(ReturnCode.ALREADYDONE, "库存不足");//测试事务是否正常

    }

    @Override
    public void saveben() {
        cache.put("a", 2);
        Class<? extends Map> aClass = cache.getClass();
        Class<?>[] classes = aClass.getClasses();
        System.out.println(classes);
    }

    @Override
    public void saveben2() {
        Object a = cache.get("a");
        //System.out.println(cache);

        Class<? extends Map> aClass = cache.getClass();
        Class<?>[] classes = aClass.getClasses();
        System.out.println(classes);

    }
}
